﻿using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using SoftSource.Common;
using SoftSource.Timecard.Entry.Converters;
using SoftSource.Timecard.Web.Data;

namespace SoftSource.Timecard.Entry.Controls
{
    public sealed class ProjectComboBox : ComboBox
    {
        private PagedCollectionView source;

        public ProjectComboBox()
        {
            this.DefaultStyleKey = typeof(ProjectComboBox);

            Loaded += new RoutedEventHandler(ProjectComboBox_Loaded);
            this.SelectionChanged += new SelectionChangedEventHandler(ProjectComboBox_SelectionChanged);
        }

        void ProjectComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ProjectSummary summary = this.SelectedItem as ProjectSummary;
            if (summary != null)
                this.ProjectID = summary.ProjectID;
        }

        void ProjectComboBox_Loaded(object sender, RoutedEventArgs e)
        {
            if (App.Model != null)
            {
                int originalID = this.ProjectID;

                this.source = new PagedCollectionView(App.Model.ProjectSummaries.Entities);
                this.source.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
                this.Filter = this.source.AttachFilter<ProjectSummary>();

                this.Filter.Add(summary =>
                    {
                        int status = summary.StatusID;
                        bool include = false;

                        switch (status)
                        {
                            case ProjectStatus.Active:
                                if (this.Active)
                                    include = true;
                                break;
                            case ProjectStatus.Completed:
                                if (this.Completed)
                                    include = true;
                                break;
                            case ProjectStatus.Suspended:
                                if (this.Suspended)
                                    include = true;
                                break;
                            case ProjectStatus.Delayed:
                                if (this.Delayed)
                                    include = true;
                                break;
                            case ProjectStatus.NotStarted:
                                if (this.NotStarted)
                                    include = true;
                                break;
                            default:
                                include = false;
                                break;
                        }

                        return include;
                    });

                this.DisplayMemberPath = "Name";
                this.ItemsSource = this.source;
                this.ProjectID = originalID;

                if (this.ProjectID != Project.InvalidProjectID)
                    this.SelectedItem = App.Model.ProjectSummaries.Entities.Where(ps => ps.ProjectID == this.ProjectID).SingleOrDefault();

                Binding projectBinding = new Binding("ProjectID");
                projectBinding.Source = this;
                projectBinding.Converter = new ProjectIDConverter();
                projectBinding.Mode = BindingMode.TwoWay;
                this.SetBinding(ComboBox.SelectedItemProperty, projectBinding);
            }
        }

        private void RunFilters()
        {
            if (this.Filter != null)
                this.Filter.Refresh.TryInvoke();
        }

        #region Dependency Properties
        [Category("Timecard")]
        [Description("The ID of the current project")]
        public int ProjectID
        {
            get { return (int)GetValue(ProjectIDProperty); }
            set { SetValue(ProjectIDProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ProjectID.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ProjectIDProperty =
            DependencyProperty.Register("ProjectID", typeof(int), typeof(ProjectComboBox), new PropertyMetadata(Project.InvalidProjectID));


        [Category("Timecard")]
        [Description("Filters projects with custom predicates")]
        public Filter<ProjectSummary> Filter
        {
            get { return (Filter<ProjectSummary>)GetValue(FilterProperty); }
            set { SetValue(FilterProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Filter.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FilterProperty =
            DependencyProperty.Register("Filter", typeof(Filter<ProjectSummary>), typeof(ProjectComboBox), new PropertyMetadata(null));



        [Category("Timecard")]
        [Description("Filters projects that have been categorized as \'Active\'")]
        public bool Active
        {
            get { return (bool)GetValue(ActiveProperty); }
            set { SetValue(ActiveProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Active.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ActiveProperty =
            DependencyProperty.Register("Active", typeof(bool), typeof(ProjectComboBox), new PropertyMetadata(true, (sender, args) =>
            {
                ProjectComboBox cb = sender as ProjectComboBox;
                if (cb != null)
                    cb.RunFilters();
            }));


        [Category("Timecard")]
        [Description("Filters projects that have been categorized as \'Completed\'")]
        public bool Completed
        {
            get { return (bool)GetValue(CompletedProperty); }
            set { SetValue(CompletedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Completed.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CompletedProperty =
            DependencyProperty.Register("Completed", typeof(bool), typeof(ProjectComboBox), new PropertyMetadata(false, (sender, args) =>
            {
                ProjectComboBox cb = sender as ProjectComboBox;
                if (cb != null)
                    cb.RunFilters();
            }));


        [Category("Timecard")]
        [Description("Filters projects that have been categorized as \'Suspended\'")]
        public bool Suspended
        {
            get { return (bool)GetValue(SuspendedProperty); }
            set { SetValue(SuspendedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Suspended.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SuspendedProperty =
            DependencyProperty.Register("Suspended", typeof(bool), typeof(ProjectComboBox), new PropertyMetadata(false, (sender, args) =>
            {
                ProjectComboBox cb = sender as ProjectComboBox;
                if (cb != null)
                    cb.RunFilters();
            }));


        [Category("Timecard")]
        [Description("Filters projects that have been categorized as \'Delayed\'")]
        public bool Delayed
        {
            get { return (bool)GetValue(DelayedProperty); }
            set { SetValue(DelayedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Delayed.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DelayedProperty =
            DependencyProperty.Register("Delayed", typeof(bool), typeof(ProjectComboBox), new PropertyMetadata(false, (sender, args) =>
            {
                ProjectComboBox cb = sender as ProjectComboBox;
                if (cb != null)
                    cb.RunFilters();
            }));

        [Category("Timecard")]
        [Description("Filters projects that have been categorized as \'Not Started\'")]
        public bool NotStarted
        {
            get { return (bool)GetValue(NotStartedProperty); }
            set { SetValue(NotStartedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NotStarted.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NotStartedProperty =
            DependencyProperty.Register("NotStarted", typeof(bool), typeof(ProjectComboBox), new PropertyMetadata(false, (sender, args) =>
            {
                ProjectComboBox cb = sender as ProjectComboBox;
                if (cb != null)
                    cb.RunFilters();
            }));        
        #endregion Dependency Properties
    }
}
